/*
 * queue.hpp
 *
 *  Created on: 2011-3-25
 *      Author: wangyn001
 */

#ifndef QUEUE_HPP_
#define QUEUE_HPP_
#include <unistd.h>
#include <semaphore.h>
using namespace std;

template<class Elem> class Queue {
public:
	virtual void clear() = 0;
	virtual bool enqueue(const Elem&) = 0;
	virtual void dequeue(Elem&) = 0;
	virtual bool frontValue(Elem&) const = 0;
	virtual int length() const = 0;
};

template<class Elem> class Queue1: public Queue<Elem> {
private:
	int num;
	int size;
	int front;
	int rear;
	Elem*listArray;
	sem_t Sem;

public:

	Queue1(int sz) {
		size = sz;
		rear = 0;
		front = 0;
		listArray = new Elem[size];
		num = 0;
		sem_init(&Sem, 0, 0);
	}

	~Queue1() {
		delete[] listArray;
		sem_destroy(&Sem);
	}

	void clear() {
		front = rear;
		num = 0;
	}

	bool enqueue(const Elem& it) {
		if (length() == size)
			return false;
		listArray[rear] = it;
		rear = (rear + 1) % size;
		num++;
		sem_post(&Sem);
		return true;
	}

	void  dequeue(Elem& it) {
		sem_wait(&Sem);
		it = listArray[front];
		front = (front + 1)%size;
		num--;
	}

	bool frontValue(Elem& it) const {
		if (length() == 0)
			return false;
		it = listArray[front];
		return true;
	}

	int length() const {
		return num;
	}
};

#endif /* QUEUE_HPP_ */
